package heven.holt.wan.android.viewmodel

import androidx.lifecycle.*
import dagger.hilt.android.lifecycle.HiltViewModel
import heven.holt.wan.android.extensions.requestCoroutine
import heven.holt.wan.android.model.ArticleModel
import heven.holt.wan.android.model.NavigationModel
import heven.holt.wan.android.model.ProjectModel
import heven.holt.wan.android.repository.WanNavigationRepository
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class NavigationViewModel @Inject constructor(
    private val wanNavigationRepository: WanNavigationRepository,
    private val savedStateHandle: SavedStateHandle
) : ViewModel() {
    companion object {
        private const val SELECT_NAVIGATION_NONE = -1
        private const val SELECT_NAVIGATION_MENU_CID = "SELECT_NAVIGATION_MENU_CID"
    }


    private val currentCid: MutableStateFlow<Int> = MutableStateFlow(
        savedStateHandle.get(SELECT_NAVIGATION_MENU_CID) ?: SELECT_NAVIGATION_NONE
    )

    val navigationListLiveData: MutableLiveData<List<NavigationModel>> = MutableLiveData()

    val navigationContentListLiveData: LiveData<List<ArticleModel>> = currentCid.mapLatest { cid ->
        if (cid == SELECT_NAVIGATION_NONE) {
            val list = requestNavigationList()
            val first = list.firstOrNull()?.also { it.isSelect = true }
            navigationListLiveData.postValue(list)
            first?.articles ?: emptyList()
        } else {
            if (navigationListLiveData.value == null) {
                val list = requestNavigationList()
                list.find { cid == it.cid }?.also { it.isSelect = true }
                navigationListLiveData.value = list
            }
            navigationListLiveData.value?.find { cid == it.cid }?.articles ?: emptyList()
        }
    }.asLiveData()

    val navigationProjectSystemListLiveData: MutableLiveData<List<ProjectModel>> = MutableLiveData()

    val navigationProjectModelLiveData: MutableLiveData<ProjectModel> = MutableLiveData()

    init {
        viewModelScope.launch {
            currentCid.collect { newCid ->
                savedStateHandle.set(SELECT_NAVIGATION_MENU_CID, newCid)
            }
        }
    }

    private suspend fun requestNavigationList() = requestCoroutine {
        wanNavigationRepository.getNavigationList()
    } ?: emptyList()

    fun requestProjectSystemList() {
        viewModelScope.launch {
            val projectList =
                requestCoroutine { wanNavigationRepository.getProjectList() } ?: return@launch
            navigationProjectSystemListLiveData.postValue(projectList)
        }
    }

    fun requestProjectModelByCid() {
        viewModelScope.launch {
            val projectList = navigationProjectSystemListLiveData.value
                ?: requestCoroutine { wanNavigationRepository.getProjectList() } ?: return@launch
            val projectModel =
                wanNavigationRepository.getProjectModelByCid(projectList, currentCid.value) ?: return@launch
            navigationProjectModelLiveData.postValue(projectModel)
        }
    }

    fun requestPositionByProjectTree(projectModel: ProjectModel) =
        wanNavigationRepository.getPositionByProjectTree(projectModel, currentCid.value)

    fun setCurrentCid(cid: Int) {
        currentCid.value = cid
    }
}